package ciel.menu;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.mt4j.components.TransformSpace;
import org.mt4j.components.visibleComponents.shapes.MTEllipse;
import org.mt4j.input.inputProcessors.IGestureEventListener;
import org.mt4j.input.inputProcessors.MTGestureEvent;
import org.mt4j.input.inputProcessors.componentProcessors.tapProcessor.TapEvent;
import org.mt4j.input.inputProcessors.componentProcessors.tapProcessor.TapProcessor;
import org.mt4j.util.MTColor;
import org.mt4j.util.animation.Animation;
import org.mt4j.util.animation.AnimationEvent;
import org.mt4j.util.animation.IAnimationListener;
import org.mt4j.util.animation.MultiPurposeInterpolator;
import org.mt4j.util.math.Vector3D;
import org.mt4j.util.math.Vertex;

import processing.core.PApplet;
import ciel.image.CielThumbnail;
import ciel.res.CielSettings;

public class CielThumbnailMenu extends MTEllipse {
	
	private ArrayList<CielThumbnail> thumbs;
	public int position;
	private float radius;
	public Vector3D center;

	public CielThumbnailMenu(PApplet pApplet, Vector3D centerPoint,
			float radiusX, float radiusY) {
		super(pApplet, centerPoint, radiusX, radiusY);
		position = CielSettings.Positions.BOTTOM_LEFT;
		init();
		addCloseOption(pApplet);
	}

	private void init() {
		
		thumbs  = new ArrayList<CielThumbnail>();
		removeAllGestureEventListeners();
		setNoStroke(true);
		setNoFill(true);
		
		
		setWidthXYGlobal((CielSettings.Dimensions.userButtonRadius * 6));
		setHeightXYGlobal(CielSettings.Dimensions.userButtonRadius * 6);
		
		radius = getWidthXYGlobal()/2;
		
		rotateZGlobal(getCenterPointGlobal(), 85);
		
		setVisible(false);
		setDegrees(100);
		create();
		
		Vertex[] verts = getVerticesLocal();
		verts[verts.length-2] = new Vertex(getCenterPointLocal());
		setVertices(verts);
		setPositionGlobal(new Vector3D(0, CielSettings.Dimensions.SCREEN_HEIGHT));
		
		setNoFill(false);
		setFillColor(new MTColor(100,100,100,100));
		setNoStroke(false);
		setStrokeColor(new MTColor(200,200,200,200));
		setStrokeWeight(5);
	}
	
	private void addCloseOption(PApplet pApplet) {

		TapProcessor tp = new TapProcessor(pApplet);
		tp.setEnableDoubleTap(true);
		registerInputProcessor(tp);
		
		addGestureListener(TapProcessor.class, new IGestureEventListener() {
			public boolean processGestureEvent(MTGestureEvent ge) {	
				TapEvent te = (TapEvent)ge;
				if(te.isDoubleTap()) {
					setVisible(false);
				}
				return false;
			}
		});
	}
	
	private void closeWithAnimation() {
		float width = this.getWidthXY(TransformSpace.RELATIVE_TO_PARENT);
		Animation imageCloseAnimation = new Animation("Menu Fade Out", new MultiPurposeInterpolator(width, 1, 300, 0.2f, 0.5f, 1), this);
		imageCloseAnimation.addAnimationListener(new IAnimationListener(){
			public void processAnimationEvent(AnimationEvent ae) {
				switch (ae.getId()) {
				case AnimationEvent.ANIMATION_STARTED:
				case AnimationEvent.ANIMATION_UPDATED:
					float currentVal = ((Animation) ae.getAnimation()).getInterpolator().getCurrentValue();
					setWidthXYRelativeToParent(currentVal);
					break;
				case AnimationEvent.ANIMATION_ENDED:
					setVisible(false);
					break;	
				default:
					break;
				}
			}
		});

		imageCloseAnimation.start();
	}
	
	public void openWithAnimation() {
		Animation imageOpenAnimaion = new Animation("Menu Fade In", new MultiPurposeInterpolator(1, radius, 500, 0.2f, 0.5f, 1), this);
		imageOpenAnimaion.addAnimationListener(new IAnimationListener(){
			public void processAnimationEvent(AnimationEvent ae) {
				switch (ae.getId()) {
				case AnimationEvent.ANIMATION_STARTED:
				case AnimationEvent.ANIMATION_UPDATED:
					float currentVal = ((Animation) ae.getAnimation()).getInterpolator().getCurrentValue();
					setWidthXYRelativeToParent(currentVal);
					break;
				case AnimationEvent.ANIMATION_ENDED:
					setVisible(true);
					break;	
				default:
					break;
				}
			}
		});
		imageOpenAnimaion.start();
	}
	
	public void addThumbs(HashMap<String, CielThumbnail> thumbs) {
		for(Map.Entry<String, CielThumbnail> thumb: thumbs.entrySet()) {
			((CielThumbnail) thumb.getValue()).setName(thumb.getKey());
			this.thumbs.add(((CielThumbnail) thumb.getValue()));
			placeThumb(((CielThumbnail) thumb.getValue()));
		}
	}
	
	public void addThumb(CielThumbnail thumb) {
		this.thumbs.add(thumb);
		placeThumb(thumb);
	}
	
	private void placeThumb(CielThumbnail tmpNail) {
		boolean placed = false;
		float randomX = getCenterPointGlobal().x;
		float randomY = getCenterPointGlobal().y;
		float wm = getWidthXYGlobal();
		
		while(!placed){
			switch(position) {
				case CielSettings.Positions.BOTTOM_LEFT:
					randomX = (float) (Math.random() * wm);
					randomY = CielSettings.Dimensions.SCREEN_HEIGHT - (float) (Math.random() * wm);
					break;
				case CielSettings.Positions.TOP_LEFT:
					randomX = (float) (Math.random() * wm);
					randomY = (float) (Math.random() * wm);
					break;
				case CielSettings.Positions.TOP_RIGHT:
					randomX = CielSettings.Dimensions.SCREEN_WIDTH - (float) (Math.random() * wm);
					randomY = (float) (Math.random() * wm);
					break;
				case CielSettings.Positions.BOTTOM_RIGHT:
					randomX = CielSettings.Dimensions.SCREEN_WIDTH - (float) (Math.random() * wm);
					randomY = CielSettings.Dimensions.SCREEN_HEIGHT - (float) (Math.random() * wm);
					break;
				default:
					randomX = (float) (Math.random() * wm);
					randomY = CielSettings.Dimensions.SCREEN_HEIGHT - (float) (Math.random() * wm);
					break;
			}
			addChild(tmpNail);
			tmpNail.setPositionGlobal(new Vector3D(randomX, randomY));
			tmpNail.rotateZ(getCenterPointLocal(), (float) Math.random() * 75);
			
			if(isInMenu(tmpNail)) {
				placed =  true;
				tmpNail.setNoStroke(true);
				tmpNail.setStrokeWeight(0);
				tmpNail.setUserData("lastPosition", new Vector3D(randomX, randomY));
			} else removeChild(tmpNail);
		}
	}
	
	private boolean isInMenu(CielThumbnail thumb) {
		Vertex[] verticies = thumb.getVerticesGlobal();
		for(Vertex v: verticies) {
			if(!this.containsPointGlobal(v)) return false;
		}
		return true;
	}	

	
}
